home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-08-05 | 47.9 KB | 2,226 lines |
- Path: uunet!rs
- From: rs@uunet.UU.NET (Rich Salz)
- Newsgroups: comp.sources.unix
- Subject: v10i091: A graphics editor, Part01/04
- Message-ID: <777@uunet.UU.NET>
- Date: 6 Aug 87 20:25:26 GMT
- Organization: UUNET Communications Services, Arlington, VA
- Lines: 2215
- Approved: rs@uunet.UU.NET
-
- Submitted-by: "Alan W. Paeth" <awpaeth%watcgl.waterloo.edu@RELAY.CS.NET>
- Posting-number: Volume 10, Issue 91
- Archive-name: lemming/Part01
-
- LEMMING is a complete interactive graphics editor which resembles PIC in
- providing lines, boxes, circles, and text in various sizes and
- emphases (bold, centered, dotted, etc). The implemtation has been proven
- on the DEC GPX systems, SUN, and Ikonas Framebuffer. The code is completely
- self-contained, and provides an extensive set of internal fonts.
-
- Lemming makes no assumptions about the system hardware except that there
- is (1) a mouse or tablet with at least one button and (2) there is a bitmap
- display (at least one bit deep). The additional code (lemik.c) is a
- representative Unix driver for use with an Ikonas framebuffer.
-
-
- I am allowing complete public distribution and second party redistribution
- of the software on an experimental, non-profit basis. I maintain a
- copyright against unauthorized sale or distribution for commercial or
- product applications.
-
- Alan Paeth (awpaeth@watmath)
- c/o Computer Graphics Lab MC6080
- University of Waterloo
- Waterloo, Ontario N2L 3E5
- CANADA
-
-
- [ I have not tried this program. -r$ ]
- #!/bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #!/bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # Makefile
- # .lemrc
- # lem.h
- # lemfont.h
- # lemalloc.c
- # lemalpha.c
- # lemattr.c
- # lembox.c
- # lemcut.c
- # lemedit.c
- # lemelli.c
- # lemfont.c
- # lemgeo.c
- # lemglobal.c
- # lemgroup.c
- # lemhelp.c
- # lemik.c
- # lemio.c
- # lemline.c
- if test -f 'Makefile'
- then
- echo shar: over-writing existing file "'Makefile'"
- fi
- cat << \SHAR_EOF > 'Makefile'
- CFLAGS = -g
-
- OBJ = lemalloc.o \
- lemalpha.o \
- lemattr.o \
- lembox.o \
- lemcut.o \
- lemedit.o \
- lemelli.o \
- lemfont.o \
- lemgeo.o \
- lemglobal.o \
- lemgroup.o \
- lemhelp.o \
- lemio.o \
- lemline.o \
- lemmain.o \
- lemmark.o \
- lemmisc.o \
- lemobj.o \
- lemobjsup.o \
- lemop.o \
- lempic.o \
- lemrc.o \
- lemselect.o \
- lemspecial.o \
- lemstart.o \
- lemstop.o \
- lemtext.o \
- lemtick.o \
- lemundo.o \
- lemvec.o
-
- lemik:: $(OBJ) lemik.o
- cc $(CFLAGS) $(OBJ) lemik.o -lIkonas -lLocator -lm -o /u/awpaeth/bin/lemik
-
- lemx:: $(OBJ) lemx.o
- cc $(CFLAGS) $(OBJ) lemx.o -lX -lm -o /u/awpaeth/bin/lemx
- SHAR_EOF
- chmod +x 'Makefile'
- if test -f '.lemrc'
- then
- echo shar: over-writing existing file "'.lemrc'"
- fi
- cat << \SHAR_EOF > '.lemrc'
- .lemrc
- Lemming .rc for default fonts (up to nine).
- Data items are identified by a digit in the left-most column.
-
- Note: substitue MR MB & MI for TR TB TI if you (*ugh*) must have ugly fonts.
-
- |----------------------- Fonts ------------------------------|
- Pnt Line |Display Typeset PostScript |
- Sz Thkn Rg/Bld/Itl Rg/Bld/Itl
- ------------------------------------------------------------------------
- 12 1 TimesRoman TR TB TI Times-Bold Times-Bold Times-Bold
- 10 2 TimesRoman TR TB TI Times-Bold Times-Bold Times-Bold
- 18 3 TimesRoman TR TB TI Times-Bold Times-Bold Times-Bold
- 12 4 Helvetica SR SB SI Times-Bold Times-Bold Times-Bold
- 10 5 Helvetica SR SB SI Times-Bold Times-Bold Times-Bold
- 18 6 Helvetica SR SB SI Times-Bold Times-Bold Times-Bold
- 6 7 Helvetica SR SB SI Times-Bold Times-Bold Times-Bold
- 10 8 Gacha CW CW CW Times-Bold Times-Bold Times-Bold
- 12 9 Hippo GM GM GM Times-Bold Times-Bold Times-Bold
-
- Other popular entries (delete leading space):
-
- 18 1 OldEnglish oe oe oe Times-Bold Times-Bold Times-Bold
- SHAR_EOF
- chmod +x '.lemrc'
- if test -f 'lem.h'
- then
- echo shar: over-writing existing file "'lem.h'"
- fi
- cat << \SHAR_EOF > 'lem.h'
- /*
- * lem.h - lone include file for lem(ming) editor
- *
- * copyright (c) by Alan W. Paeth, 1987. All rights reserved.
- */
-
- #include <stdio.h>
- #include <strings.h>
- #include <ctype.h>
-
- #define VERNO 1
-
- /*
- * useful arithmetic functions
- */
-
- #define MIN(a,b) ((a)<(b)?(a):(b))
- #define MAX(a,b) ((a)>(b)?(a):(b))
- #define ABS(a) ((a)>0?(a):(-(a)))
- #define C(a) ('a'&0x1f)
- #define UC(c) (islower((c)) ? toupper((c)) : (c))
-
- typedef struct
- {
- char stat; /* DEL, UNDEL, SEL */
- char group; /* group id (or zero) */
- char type; /* LINE, TEXT, ELLI, BOX */
- char align; /* ALIGNLEFT, ALIGNRGHT, ALIGNCENT */
- char emph; /* EMPHNONE, EMPHBOLD, EMPHITAL */
- char size; /* 1..10 */
- short x0, y0, x1, y1; /* screen coordinates/bounding box */
- char *text; /* string pointer if text */
- } *pel, el;
-
- /*
- * object macros
- */
-
- #define forobjects for(i=1; i<lastobj; i++)
- #define forobjsrev for(i=lastobj-1; i>0; i--)
- #define o objs[i]
-
- /*
- * field access
- */
-
- #define Ostat (o->stat)
- #define Ogroup (o->group)
- #define Otype (o->type)
- #define Oalign (o->align)
- #define Oemph (o->emph)
- #define Osize (o->size)
- #define Osizer ((Osize >= rclen) ? 1 : Osize)
- #define Otext (o->text)
- #define Oxs (o->x0)
- #define Oys (o->y0)
- #define Oxe (o->x1)
- #define Oye (o->y1)
-
- /*
- * derived field access
- */
-
- #define Ox ((o->x0+o->x1+1)/2)
- #define Oy ((o->y0+o->y1+1)/2)
- #define Ow (o->x1-o->x0)
- #define Oh (o->y1-o->y0)
- #define Oxl (MIN(o->x0,o->x1))
- #define Oyl (MIN(o->y0,o->y1))
- #define Oxh (MAX(o->x0,o->x1))
- #define Oyh (MAX(o->y0,o->y1))
-
- #define Oxlt (Oalign==ALIGNCENT ? Oxs-Oxe/2:(Oalign==ALIGNLEFT ? Oxs:Oxs-Oxe))
- #define Oylt (Oys-Oye/2)
- /* (Oalign==ALIGNCENT ? Oyl : (Oalign==ALIGNLEFT ? Oy : Oy-Oh)) */
- #define Oxht (Oxlt+Oxe)
- #define Oyht (Oylt+Oye)
- #define Oxcen (Otype==TEXT ? Oxs : Ox)
- #define Oycen (Otype==TEXT ? Oys : Oy)
-
- #define Osel (o->stat == SEL)
- #define Oundel (o->stat == UNDEL)
- #define Odel (o->stat == DEL)
- #define Onotdel (o->stat != DEL)
-
- /*
- * bounds limits
- */
-
- #define MAXOBJS 2000
- #define MAXCHAR 60
-
- /*
- * .lemrc information
- */
-
- typedef struct
- {
- int psize;
- int thick;
- char *dsp;
- char *tyr;
- char *tyb;
- char *tyi;
- char *psr;
- char *psb;
- char *psi;
- } *pfontdir, fontdir;
-
-
- /*
- * file name (conventions)
- */
-
- #define RCNAME ".lemrc"
- #define LEMEXTN "lem"
-
- /*
- * initialization defaults (for .rc file in lemrc.c)
- */
-
- #define RCLINE 120
- #define RCLEN 10
- #define RCWIDTH 9
-
- #define DEFPSIZEFT 12
- #define DEFDENSEFT 1.0
- #define DEFIKRFT "TimesRoman"
- #define DEFTYRFT "TR"
- #define DEFTYBFT "TB"
- #define DEFTYIFT "TB"
- #define DEFPSRFT "Times-Roman"
- #define DEFPSBFT "Times-Bold"
- #define DEFPSIFT "Times-Italic"
-
- /*
- * system color aliases
- */
-
- #define DRAWCOL cwhite
- #define SELECTCOL cred
- #define ERASECOL cblack
- #define MARKONOBJCOL cred
- #define MARKONREGCOL cgreen
- #define HELPCOL cgreen
- #define MARKOFFCOL cblack
- #define TICKONCOL cwhite
- #define TICKOFFCOL cblack
-
- /*
- * event types
- */
-
- #define NOEVT 0
- #define ALPHA 1
- #define CNTRL 2
- #define MOUSE 3
-
- /*
- * geometric tolerances
- */
-
- #define ENDTOL 5 /* near endpoints of lines */
- #define MARKTOL 5 /* near a mark */
- #define DRAGTOL 5 /* dragging otherwise */
- #define FLATTOL 15 /* rectilinear lines */
- #define SELTOL 15 /* near selection points */
- #define SHRTTOL 5 /* lines may not be (entered) any shorter */
- #define LINETOL 5 /* perp distance to a line */
- #define TEXTTOL 0 /* text bounding box extra margins (usually no slop) */
- #define SPLTTOL 3 /* do not split lines <^K> if made this short */
-
- #define TUGPROX 2 /* when towing objects */
- #define ARROWLEN 8 /* arrowhead length */
- #define MINTICK 8 /* minimum VISIBLE tick spacing */
- #define DEFCOPYWID 16 /* default copy width when gridding is off */
-
- /*
- * type modes
- */
-
- #define LINE 'L'
- #define TEXT 'T'
- #define ELLI 'E'
- #define BOX 'B'
-
- /*
- * status modes
- */
-
- #define DEL 'D'
- #define UNDEL 'U'
- #define SEL 'S'
-
- /*
- * align modes
- */
-
- #define ALIGNLEFT 'L'
- #define ALIGNRGHT 'R'
- #define ALIGNCENT 'C'
-
- /*
- * emphasis modes
- */
-
- #define EMPHNONE 'N'
- #define EMPHBOLD 'B'
- #define EMPHITAL 'I'
-
- /*
- * define system font (for help text and unknown fonts)
- */
-
- #define SYSFONT 1
-
- /*
- * generic object operations
- */
-
- #define SELECT 1
- #define DESELECT 2
- #define DELETE 3
- #define UNDELETE 4
-
- /*
- * undo flags
- */
-
- #define UNDOMOVE 'M'
- #define UNDOTUG 'T'
- #define UNDOAFF 'A'
- #define UNDODEL 'D'
- #define UNDONONE 'N'
-
- /*
- * application specific
- */
-
- #define MARKSIZE 2
-
- /*
- * externals (see also lemglobal.c)
- */
-
- extern char *firstfile;
- extern int displayon;
-
- extern int screenw, screenh, cred, cgreen, cblack, cwhite;
- extern int changes, tickflag, ticksize, tickdot, tx, ty, txoff, tyoff;
- extern int markx, marky, markon, markobj;
- extern int anysel;
- extern char gtype, galign, gemph, gsize;
-
- extern char undo;
- extern int unx, uny, unxe, unye;
- extern float un11, un12, un21, un22;
-
- extern int fontsize[RCLEN];
- extern char *picfont[RCLEN], *postfont[RCLEN], *xfont[RCLEN], *ikfont[RCLEN];
- extern float rval[RCLEN], gval[RCLEN], bval[RCLEN];
-
- extern pel objs[MAXOBJS];
- extern int lastobj;
-
- extern fontdir lemfont[RCLEN];
-
- extern int rclen;
-
- extern char line[MAXCHAR], msgtext[MAXCHAR], prompttext[MAXCHAR];
-
- /*
- * forward refenreces
- */
-
- char *salloc(), *prompt(), getstroke();
- SHAR_EOF
- if test -f 'lemfont.h'
- then
- echo shar: over-writing existing file "'lemfont.h'"
- fi
- cat << \SHAR_EOF > 'lemfont.h'
- /* lemfont.c - routines to create and access binary level strike fonts
- *
- * copywrite (c) 1985, by Alan W. Paeth. All rights reserved
- *
- * Programmed by Alan Paeth, University of Waterloo, February, 1984
- *
- * NOTE: these fonts began life as 16-bit integers, with opposite byte-
- * order conventions of the VAX. This explains the appearance of short
- * integers, and size counts done in terms of shorts.
- *
- * Also, fonts are represented as a pointer to a contiguous, variable-
- * length structure. Because the actual bitmap is the only data part
- * which varies from font to font, its declaration is ultimate in the
- * structure declaration. FONTHEADERSIZE is the short word offset to it.
- *
- * patched by Alan Paeth, May 1985, to deal with null print strings
- */
-
- /* MAX WIDTH */
-
- #define LEFT 0
- #define RIGHT screenw
- #define TOP screenh
- #define BOTTOM 0
-
- #define MAXWIDTH 1024
-
- /* BFont structure - returned by BFontload() */
-
- typedef struct BFont_type
- {
- short ascent;
- short descent;
- short mwidth;
- short rasterx; /* strike scan line length expressed in short ints */
- short widths[257]; /* 257 boundaries between a strike of 256 chars */
- short glyphs[1]; /* var len glyphs starts after FONTHEADSIZE shorts */
- } *BFont;
-
- BFont fontload();
-
- /* offset to beginning of the glyphs */
-
- #define FONTHEADERSIZE 261
-
-
- extern BFont bfont[];
- SHAR_EOF
- if test -f 'lemalloc.c'
- then
- echo shar: over-writing existing file "'lemalloc.c'"
- fi
- cat << \SHAR_EOF > 'lemalloc.c'
- /*
- * lemalloc.c -- allocation routines useful to the whole lemming family
- *
- * copyright (c) by Alan W. Paeth, 1987. All rights reserved.
- */
-
- #include "lem.h"
-
- char *salloc(s)
- char *s;
- {
- char *out;
- out = (char*)(calloc(strlen(s)+1, sizeof(char)));
- strcpy(out, s);
- return(out);
- }
-
- objfree(i)
- {
- if (Otext)
- {
- free(Otext);
- Otext = 0;
- }
- free(o);
- o = 0;
- }
-
- objalloc(t)
- {
- int i;
- if (lastobj == MAXOBJS)
- {
- forobjects
- {
- if (Odel) break;
- }
- if (i == lastobj) err("out of object space");
- objfree(i);
- }
- else
- {
- i = lastobj++;
- o = (pel)(calloc(1, sizeof(el)));
- }
- Otext = 0;
- Otype = t;
- Otype = t;
- Oalign= galign;
- Oemph = gemph;
- Osize = gsize;
- return(i);
- }
-
- objcompress()
- {
- int i, j;
- forobjects
- {
- if (Onotdel) continue; /* look for a hole */
- for(j=i+1; j<lastobj; j++)
- {
- pel tmp;
- if (objs[j]->stat == DEL) continue; /* look for non-hole */
- tmp = objs[j];
- objs[j] = objs[i];
- objs[i] = tmp;
- break;
- }
- }
- forobjsrev
- {
- if (Odel) objfree(i);
- else break;
- }
- lastobj = i+1;
- }
-
- objnew(i)
- {
- Ostat = DEL;
- Ogroup = 0;
- objectop(i, DEL, UNDEL);
- }
- SHAR_EOF
- if test -f 'lemalpha.c'
- then
- echo shar: over-writing existing file "'lemalpha.c'"
- fi
- cat << \SHAR_EOF > 'lemalpha.c'
- /*
- * lemalpha.c - text control
- *
- * copyright (c) by Alan W. Paeth, 1987. All rights reserved.
- */
-
- #include "lem.h"
-
- charadd(s, ch)
- char *s, ch;
- {
- int end;
- char str[2];
- str[0] = ch;
- str[1] = '\0';
- charshow(str);
- end = strlen(s);
- if (end < MAXCHAR-1)
- {
- s[end] = ch;
- s[end+1] = '\0';
- }
- }
-
- chardel(s,n)
- char *s;
- {
- int end;
- end = strlen(s)-n;
- if (end >= 0)
- {
- charunshow(n);
- s[end] = '\0';
- }
- }
-
- chardelall(s)
- char *s;
- {
- if (s) chardel(s, strlen(s));
- }
-
- char getstroke()
- {
- int ev, t;
- char ch;
- /*
- * get next alpha keystroke (null on other event)
- */
- do {
- ev = getevent(&t, &t, &t, &t, &ch);
- } while ((ev == NOEVT) || ((ev == CNTRL) && (ch == '\0')));
- if ((ev == ALPHA) || (ev == CNTRL)) return(ch);
- return('\0');
- }
-
- char *prompt(pstr)
- char *pstr;
- {
- char ch, pout[MAXCHAR], *rstr;
- pout[0] = '\0';
- strncpy(prompttext, pstr, MAXCHAR);
- msgclear();
- chardelall(line);
- charshow(prompttext);
- ch = '\0';
- while((ch != C(M)) && (ch != C(J)))
- {
- ch = getstroke();
- if (ch >= ' ') charadd(pout, ch);
- else if (ch == '\b') chardel(pout,1);
- }
- rstr = salloc(pout);
- chardelall(pout);
- chardelall(prompttext);
- return(rstr);
- }
-
- msgpost(s)
- char *s;
- {
- msgclear();
- strncpy(msgtext, s, MAXCHAR);
- charshow(msgtext);
- }
-
- msgclear()
- {
- chardelall(msgtext);
- }
-
- stringadd()
- {
- textadd(markx, marky, line);
- if (line && strlen(line))
- {
- int hgt;
- hgt = fontleading(gsize);
- markupdate(markx, MAX(marky-hgt, hgt));
- }
- chardelall(line);
- }
-
- fontheight(f)
- {
- return(lemfont[(f >= rclen) ? 1 : f].psize);
- }
-
- fontleading(f)
- {
- return((fontheight(f)*6+2)/5);
- }
- SHAR_EOF
- if test -f 'lemattr.c'
- then
- echo shar: over-writing existing file "'lemattr.c'"
- fi
- cat << \SHAR_EOF > 'lemattr.c'
- /*
- * lemattr.c - change object attributes (and reset global defaults)
- *
- * copyright (c) by Alan W. Paeth, 1987. All rights reserved.
- */
-
- #include "lem.h"
-
- remake(newtype)
- {
- int i;
- gtype = newtype;
- forobjects
- {
- if (Osel && (Otype != newtype) && (Otype != TEXT))
- {
- objectop(i, SEL, DEL);
- Otype = newtype;
- objectop(i, DEL, SEL);
- }
- }
- }
-
- setattr(ch)
- char ch;
- {
- switch(UC(ch))
- {
- case 'B': gemph = EMPHBOLD; break;
- case 'I': gemph = EMPHITAL; break;
- case 'N': gemph = EMPHNONE; break;
- case 'L': galign = ALIGNLEFT; break;
- case 'R': galign = ALIGNRGHT; break;
- case 'C': galign = ALIGNCENT; break;
- case '0': gsize = 1; galign = ALIGNCENT; gemph = EMPHNONE; break;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': gsize = ch-'0'; break;
- default: return(0); /* invalid char - fail */
- }
- return(1); /* good char */
- }
- /*
- * rewrite all objects with these attributes
- */
-
- forceattr()
- {
- int i, salign, semph, ssize;
- char ch;
- ch = getstroke();
- if (setattr(ch)) /* set global attributes */
- {
- salign = galign; /* save new global attributes */
- semph = gemph;
- ssize = gsize;
- forobjects
- {
- if (Osel)
- {
- objectop(i, SEL, DEL); /* get object */
- galign = Oalign; /* set matching global attribs, */
- gemph = Oemph;
- gsize = Osize;
- setattr(ch); /* reset some new attribute(s) */
- Oalign = galign; /* write back */
- Oemph = gemph;
- Osize = gsize;
- objresize(i); /* in case this changes geometry */
- objectop(i, DEL, SEL);
- }
- }
- galign = salign; /* reset to new global attributes */
- gemph = semph;
- gsize = ssize;
- }
- }
- SHAR_EOF
- if test -f 'lembox.c'
- then
- echo shar: over-writing existing file "'lembox.c'"
- fi
- cat << \SHAR_EOF > 'lembox.c'
- /*
- * lembox.c - box primitives
- *
- * copyright (c) by Alan W. Paeth, 1987. All rights reserved.
- */
-
- #include "lem.h"
-
- boxresize(i)
- {
- }
-
- boxnearpt(i, x, y)
- {
- int dx, dy;
- if (ptinrect(x, y, Oxl, Oyl, Oxh, Oyh, LINETOL))
- {
- dx = MIN(ABS(Ox-x), ABS(Oxh-x)); /* simplified for Iris C */
- dx = MIN(ABS(Oxl-x), dx);
- dy = MIN(ABS(Oy-y), ABS(Oyh-y));
- dy = MIN(ABS(Oyl-y), dy);
- if ((dx < ENDTOL) && (dy < 2*ENDTOL)) return(1);
- if ((dx < 2*ENDTOL) && (dy < ENDTOL)) return(1);
- }
- return(0);
- }
-
- boxinrect(i, xl, yl, xh, yh)
- {
- return(objsupinrect(i, xl, yl, xh, yh));
- }
-
- boxcantug(i, x, y)
- {
- return(objsupcantug(i, x, y));
- }
-
- boxtug(i, xs, ys, xe, ye)
- {
- int lx, mx, hx, ly, my, hy;
- lx = ABS(Oxl-xs);
- mx = ABS(Ox-xs);
- hx = ABS(Oxh-xs);
- if (lx<mx && lx<hx) { if (Oxs<Oxe) Oxs = xe; else Oxe = xe; }
- if (hx<lx && hx<mx) { if (Oxs>Oxe) Oxs = xe; else Oxe = xe; }
- ly = ABS(Oyl-ys);
- my = ABS(Oy-ys);
- hy = ABS(Oyh-ys);
- if (ly<my && ly<hy) { if (Oys<Oye) Oys = ye; else Oye = ye; }
- if (hy<ly && hy<my) { if (Oys>Oye) Oys = ye; else Oye = ye; }
- if (mx<=hx && mx<=lx && my<=hy && my<=ly) boxmove(i, xe-xs, ye-ys);
- }
-
- boxalign(i, x, y)
- int *x, *y;
- {
- int l, m, h;
- l = ABS(Oxl-*x);
- m = ABS(Ox-*x);
- h = ABS(Oxh-*x);
- if (l<m && l<h) *x = Oxl;
- if (m<h && m<l) *x = Ox;
- if (h<=l && h<=m) *x = Oxh;
- l = ABS(Oyl-*y);
- m = ABS(Oy-*y);
- h = ABS(Oyh-*y);
- if (l<m && l<h) *y = Oyl;
- if (m<h && m<l) *y = Oy;
- if (h<=l && h<=m) *y = Oyh;
- }
-
- boxmove(i, x, y)
- {
- objsupmove(i, x, y);
- }
-
- boxaffine(i, m11, m12, m21, m22)
- float m11, m12, m21, m22;
- {
- objsupaffine(i, m11, m12, m21, m22, 1);
- }
-
- boxdraw(i, col)
- {
- int wid;
- wid = lemfont[Osizer].thick;
- drawvec(Oxs, Oys, Oxe, Oys, col, wid, Oemph);
- drawvec(Oxe, Oys, Oxe, Oye, col, wid, Oemph);
- drawvec(Oxe, Oye, Oxs, Oye, col, wid, Oemph);
- drawvec(Oxs, Oye, Oxs, Oys, col, wid, Oemph);
- }
- SHAR_EOF
- if test -f 'lemcut.c'
- then
- echo shar: over-writing existing file "'lemcut.c'"
- fi
- cat << \SHAR_EOF > 'lemcut.c'
- /*
- * lemcut.c - code for chopping against intersecting lines.
- *
- * copyright (c) by Alan W. Paeth, 1987. All rights reserved.
- */
-
- #include "lem.h"
-
- cutlines()
- {
- int i, x0, x1, y0, y1, x2, y2, x3, y3;
- forobjects
- {
- if (Osel && Otype == LINE)
- {
- x2 = Oxs;
- y2 = Oys;
- x3 = Oxe;
- y3 = Oye;
- {
- int i, j, xs, ys; /* new "i" variable */
- long det, det2, a, b;
- forobjects
- {
- if (Otype != LINE) continue;
- if (Ostat != UNDEL) continue; /* don't cut sel lines */
- x0 = Oxs;
- y0 = Oys;
- x1 = Oxe;
- y1 = Oye;
- if ((x0 == x2) && (y0 == y2)) continue; /* share endpnts */
- if ((x1 == x2) && (y1 == y2)) continue;
- if ((x0 == x3) && (y0 == y3)) continue;
- if ((x1 == x3) && (y1 == y3)) continue;
- det = (x1-x0)*(y3-y2) - (y1-y0)*(x3-x2);
- if (det == 0) continue;
- det2 = det/2;
- a = ((y3-y2)*(x2-x0) + (x2-x3)*(y2-y0));
- b = ((y1-y0)*(x2-x0) + (x0-x1)*(y2-y0));
- if (a == 0) continue;
- if ((a < 0) && (a <= det)) continue;
- if ((a > 0) && (a >= det)) continue;
- if ((b < 0) && (b <= det)) continue;
- if ((b > 0) && (b >= det)) continue;
- xs = x0 + (a*(x1-x0)+det2)/det;
- ys = y0 + (a*(y1-y0)+det2)/det;
- if (dist(x0, y0, xs, ys) <= SPLTTOL) continue;
- if (dist(x1, y1, xs, ys) <= SPLTTOL) continue;
- objectop(i, UNDEL, DEL);
- j = objalloc(LINE);
- copyattr(j, i);
- lineupdate(i, x0, y0, xs, ys);
- lineupdate(j, xs, ys, x1, y1);
- objectop(i, DEL, UNDEL);
- objectop(j, DEL, UNDEL);
- }
- }
- }
- }
- }
- SHAR_EOF
- if test -f 'lemedit.c'
- then
- echo shar: over-writing existing file "'lemedit.c'"
- fi
- cat << \SHAR_EOF > 'lemedit.c'
- /*
- * lemedit.c - object manipulation
- *
- * copyright (c) by Alan W. Paeth, 1987. All rights reserved.
- */
-
- #include "lem.h"
-
- moveselect(x, y)
- {
- int i;
- /*
- * set flag and record last movement for undo
- */
- unx = x;
- uny = y;
- undo = UNDOMOVE;
- /*
- * do the move
- */
- if (!anysel) return;
- forobjects
- {
- if (Osel)
- {
- objectop(i, SEL, DEL);
- objmove(i, x, y);
- objectop(i, DEL, SEL);
- }
- }
- }
-
- tugunselect(xs, ys, xe, ye)
- {
- int i;
- /*
- * set flag and record last movement for undo
- */
- unx = xs;
- uny = ys;
- unxe = xe;
- unye = ye;
- undo = UNDOTUG;
- /*
- * do the tug
- */
- if (anysel) return;
- forobjects
- {
- if (Oundel && objcantug(i, xs, ys))
- {
- objectop(i, UNDEL, DEL);
- objtug(i, xs, ys, xe, ye);
- objectop(i, DEL, UNDEL);
- }
- }
- }
-
- copyattr(j, i)
- {
- objs[j]->stat = Ostat;
- objs[j]->type = Otype;
- objs[j]->x0 = Oxs;
- objs[j]->y0 = Oys;
- objs[j]->x1 = Oxe;
- objs[j]->y1 = Oye;
- objs[j]->align = Oalign;
- objs[j]->emph = Oemph;
- objs[j]->size = Osize;
- objs[j]->group = Ogroup;
- if (Otext) objs[j]->text = salloc(Otext);
- }
-
- copysel()
- {
- int i, j, g, dx, dy;
- if (!anysel) return;
- dx = tickflag ? tx : DEFCOPYWID;
- dy = tickflag ? ty : DEFCOPYWID;
- g = uniquegroup();
- forobjects
- {
- if (Osel)
- {
- j = objalloc(Otype);
- copyattr(j, i);
- objs[j]->x0 = Oxs+dx;
- objs[j]->y0 = Oys+dy;
- if (Otype != TEXT)
- {
- objs[j]->x1 = Oxe+dx;
- objs[j]->y1 = Oye+dy;
- }
- objs[j]->group = g;
- objs[j]->stat = DEL;
- objectop(i, SEL, UNDEL);
- objectop(j, DEL, UNDEL);
- }
- }
- if (markobj) markupdate(markx+dx, marky+dy);
- }
- SHAR_EOF
- if test -f 'lemelli.c'
- then
- echo shar: over-writing existing file "'lemelli.c'"
- fi
- cat << \SHAR_EOF > 'lemelli.c'
- /*
- * lemselect.c - object selection and proximity testing
- *
- * copyright (c) by Alan W. Paeth, 1987. All rights reserved.
- */
-
- #include "lem.h"
-
- elliresize(i)
- {
- }
-
- ellinearpt(i, x, y)
- {
- if (ptinrect(x, y, Oxl, Oyl, Oxh, Oyh, LINETOL))
- {
- if (dist(Ox, Oyh, x, y) < ENDTOL) return(1);
- if (dist(Ox, Oyl, x, y) < ENDTOL) return(1);
- if (dist(Oxl, Oy, x, y) < ENDTOL) return(1);
- if (dist(Oxh, Oy, x, y) < ENDTOL) return(1);
- if (dist(Ox, Oy, x, y) < ENDTOL) return(1);
- }
- return(0);
- }
-
- elliinrect(i, xl, yl, xh, yh)
- {
- return(objsupinrect(i, xl, yl, xh, yh));
- }
-
- ellicantug(i, x, y)
- {
- return(objsupcantug(i, x, y));
- }
-
- ellitug(i, xs, ys, xe, ye)
- {
- int n, s, e, w, c;
- n = dist(Ox, Oyh, xs, ys);
- s = dist(Ox, Oyl, xs, ys);
- w = dist(Oxl, Oy, xs, ys);
- e = dist(Oxh, Oy, xs, ys);
- c = dist(Ox, Oy, xs, ys);
- if (n<s && n<e && n<w && n<c) { if (Oys>Oye) Oys = ye; else Oye = ye; }
- if (s<n && s<e && s<w && s<c) { if (Oys<Oye) Oys = ye; else Oye = ye; }
- if (e<w && e<n && e<s && e<c) { if (Oxs>Oxe) Oxs = xe; else Oxe = xe; }
- if (w<e && w<n && w<s && w<c) { if (Oxs<Oxe) Oxs = xe; else Oxe = xe; }
- if (c<=n && c<=s && c<=e && c<=w) ellimove(i, xe-xs, ye-ys);
- }
-
- ellialign(i, x, y)
- int *x, *y;
- {
- int n, s, e, w, c;
- n = dist(Ox, Oyh, *x, *y);
- s = dist(Ox, Oyl, *x, *y);
- w = dist(Oxl, Oy, *x, *y);
- e = dist(Oxh, Oy, *x, *y);
- c = dist(Ox, Oy, *x, *y);
- *x = Ox;
- *y = Oy;
- if (n<s && n<e && n<w && n<c) *y = Oyh;
- if (s<n && s<e && s<w && s<c) *y = Oyl;
- if (e<w && e<n && e<s && e<c) *x = Oxh;
- if (w<=e && w<=n && w<=s && w<=c) *x = Oxl;
- }
-
- ellimove(i, x, y)
- {
- objsupmove(i, x, y);
- }
-
- elliaffine(i, m11, m12, m21, m22)
- float m11, m12, m21, m22;
- {
- objsupaffine(i, m11, m12, m21, m22, 1);
- }
-
- ellidraw(i, col)
- {
- int wid, hw2, hh2, hw7, hh7;
- wid = lemfont[Osizer].thick;
- hw2 = ABS(Ow)/4;
- hh2 = ABS(Oh)/4;
- hw7 = ABS(Ow)*7/16;
- hh7 = ABS(Oh)*7/16;
- drawvec(Oxl, Oy, Ox-hw7, Oy+hh2, col, wid, Oemph);
- drawvec(Ox-hw7, Oy+hh2, Ox-hw2, Oy+hh7, col, wid, Oemph);
- drawvec(Ox-hw2, Oy+hh7, Ox, Oyh, col, wid, Oemph);
- drawvec(Ox, Oyh, Ox+hw2, Oy+hh7, col, wid, Oemph);
- drawvec(Ox+hw2, Oy+hh7, Ox+hw7, Oy+hh2, col, wid, Oemph);
- drawvec(Ox+hw7, Oy+hh2, Oxh, Oy, col, wid, Oemph);
- drawvec(Oxh, Oy, Ox+hw7, Oy-hh2, col, wid, Oemph);
- drawvec(Ox+hw7, Oy-hh2, Ox+hw2, Oy-hh7, col, wid, Oemph);
- drawvec(Ox+hw2, Oy-hh7, Ox, Oyl, col, wid, Oemph);
- drawvec(Ox, Oyl, Ox-hw2, Oy-hh7, col, wid, Oemph);
- drawvec(Ox-hw2, Oy-hh7, Ox-hw7, Oy-hh2, col, wid, Oemph);
- drawvec(Ox-hw7, Oy-hh2, Oxl, Oy, col, wid, Oemph);
- }
- SHAR_EOF
- if test -f 'lemfont.c'
- then
- echo shar: over-writing existing file "'lemfont.c'"
- fi
- cat << \SHAR_EOF > 'lemfont.c'
- /*
- * lemfont.c - routines to create and access binary level strike fonts
- *
- * copyright (c) by Alan W. Paeth, 1987. All rights reserved.
- *
- * Programmed by Alan Paeth, University of Waterloo, February, 1984
- *
- * NOTE: these fonts began life as 16-bit integers, with opposite byte-
- * order conventions of the VAX. This explains the appearance of short
- * integers, and size counts done in terms of shorts.
- *
- * Also, fonts are represented as a pointer to a contiguous, variable-
- * length structure. Because the actual bitmap is the only data part
- * which varies from font to font, its declaration is ultimate in the
- * structure declaration. FONTHEADERSIZE is the short word offset to it.
- *
- * patched by Alan Paeth, May 1985, to deal with null print strings
- */
-
- #include "lem.h"
- #include "lemfont.h"
-
- /* system constants */
-
- #define NULL 0
- #define READMODE 0
- #define OPENFAIL -1
-
- /* bit masking constants useful with non sign-extended shifts */
-
- #define MAXPOS 0x77777777
- #define MAXNEG 0x80000000
-
- /* private tables to speed up bit test operations */
-
- short intab[17] =
- { 0x0000,
- 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
- 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000 };
-
- int outtab[33] =
- { 0x00000000,
- 0x00000001, 0x00000002, 0x00000004, 0x00000008,
- 0x00000010, 0x00000020, 0x00000040, 0x00000080,
- 0x00000100, 0x00000200, 0x00000400, 0x00000800,
- 0x00001000, 0x00002000, 0x00004000, 0x00008000,
- 0x00010000, 0x00020000, 0x00040000, 0x00080000,
- 0x00100000, 0x00200000, 0x00400000, 0x00800000,
- 0x01000000, 0x02000000, 0x04000000, 0x08000000,
- 0x10000000, 0x20000000, 0x40000000, 0x80000000 };
-
-
- /* PUBLIC PROCEDURES */
-
- BFont fontload(filename)
- char *filename;
- {
- BFont curfont;
- short xxx, minascii, maxascii, ascent;
- short mwidth, descent, rasterx, height;
- int i;
- long fd, readlen;
-
- if ((fd = open(filename, READMODE)) == OPENFAIL) return (NULL);
-
- sread(fd, &xxx, 2); /* first word is a throwaway */
- sread(fd, &minascii, 2);
- sread(fd, &maxascii, 2);
- sread(fd, &mwidth, 2);
- sread(fd, &xxx, 2); /* length is a throwaway */
- sread(fd, &ascent, 2);
- sread(fd, &descent, 2);
- sread(fd, &xxx, 2); /* xoffset unused unless kerned fonts */
- sread(fd, &rasterx, 2);
-
- height = ascent + descent;
-
- curfont = (BFont)(calloc( rasterx*height + FONTHEADERSIZE , 2));
- if (curfont == NULL)
- {
- close(fd);
- return (NULL);
- }
-
- curfont->ascent = ascent;
- curfont->descent = descent;
- curfont->mwidth = mwidth;
- curfont->rasterx = rasterx;
-
- readlen = rasterx * height * 2; /* convert shorts to bytes */
- if (sread(fd, &(curfont->glyphs[0]), readlen) != readlen)
- {
- close(fd);
- free(curfont);
- return (NULL);
- }
-
- for (i=0; i<256; i++) curfont->widths[i] = 0;
-
- readlen = (maxascii - minascii + 2) * 2; /* n+1 widths (short ints) */
- if (sread(fd, &(curfont->widths[minascii]), readlen ) != readlen)
- {
- close(fd);
- free(curfont);
- return (NULL);
- }
- close(fd);
- return (curfont);
- }
-
- fontfree(arg)
- BFont arg;
- {
- free(arg);
- }
-
- fontmeasure(font, string, emph)
- BFont font;
- char *string;
- {
- int ch;
- int len = 0;
- if (font == NULL) err("font == NULL\n");
- while (ch = *(string++)) len += (font->widths[ch+1] - font->widths[ch]);
- if (len == 0) return(0); /* no emphasis fudge if no string */
- if (emph == EMPHITAL) len += font->ascent / 4;
- if (emph == EMPHBOLD) ++len;
- return(len);
- }
-
- fontwrite(font, x, y, string, emph, fontcol)
- {
- privfontwrite(bfont[font], x, y, string, emph, fontcol);
- }
-
- privfontwrite(font, x, y, string, emph, fontcol)
- BFont font;
- int x, y;
- char *string;
- {
- static long bitbuf[MAXWIDTH/32];
-
- int smeasure, bufsize, bufsizew, rows, inlen;
- char ch, *strcopy;
- short *inbase, *inaddr, *widthptr, inoffset;
- int i, curpos, skew, inmaski, outmaski;
- long *outaddr;
-
- y = screenh - y;
- smeasure = fontmeasure(font, string, emph);
- if (smeasure == 0) return; /* QUICK RETURN: no string */
- bufsize = MIN(x + smeasure, RIGHT) - MAX(x, LEFT);
-
- /* clip to physical resources */
-
- bufsize = MIN(bufsize, MAXWIDTH);
-
- bufsizew = (bufsize-1) / 32 + 1; /* words to hold bits, rounded up */
- inbase = &(font->glyphs[0]);
- rows = font->ascent+font->descent; /* +1 for predecrementing */
- /* y adjust */
- /* y -= 0; /* upper lh-corner */
- /* y -= font->ascent; /* lh baseline */
- /**/y -= (font->ascent+font->descent)/2; /* lh center line */
-
- ++rows;
- while (--rows) /* +1 for predecrementing speed */
- {
- if (bufsize > 0 && y >= BOTTOM && y < TOP)
- {
- if (emph == EMPHITAL)
- skew = rows / 4;
- else skew = 0;
- curpos= MIN(x+skew-LEFT,0); /* bitpos in output buffer */
- i = bufsizew;
- while (i) bitbuf[--i] = 0; /* clear ALL output buffer */
-
- strcopy = string; /* set up for output */
- outmaski = 32;
- outaddr = bitbuf;
-
- while (ch = *(strcopy++)) /* character loop */
- {
- widthptr = &(font->widths[ch]);
- inoffset = *widthptr;
-
- /* inlen is min of (room left in buffer), (char width) */
-
- inlen = min(bufsize-skew-curpos, (*(++widthptr) - inoffset) );
-
- inaddr = inbase + inoffset/16;
- inmaski = 16 - (inoffset & 15); /* 15+1 for predecrementing */
- ++inlen; /* +1 for predecrementing */
- while (--inlen) /* draw while char/room left */
- {
- if (++curpos > 0) /* position at end of draw */
- {
- if (*inaddr&intab[inmaski]) *outaddr|=outtab[outmaski];
- if (!(--outmaski)) { outmaski = 32; ++outaddr; }
- }
- if (!(--inmaski)) { inmaski = 16; ++inaddr ; }
- }
- }
- if (emph == EMPHBOLD)
- {
- for(i = bufsizew - 1; i > 0; --i)
- {
- bitbuf[i] |= (bitbuf[i])>>1;
- if (bitbuf[i-1]&1) bitbuf[i] |= MAXNEG;
- }
- bitbuf[i] |= (bitbuf[i])>>1;
- }
- /*
- if ((emph == EMPHUNDERSCORE) && (rows == font->descent))
- {
- i = bufsizew;
- while (i) bitbuf[--i] = -1;
- }
- */
- writescan( MAX(x+skew, LEFT), y, bufsize-skew, bitbuf, fontcol);
- }
- ++y;
- inbase += font->rasterx;
- }
- }
-
- /* PRIVATE PROCEDURES */
-
- static min(a,b)
- long a,b;
- {
- return( (a < b) ? a : b );
- }
-
- /*
- * sread is analogous to unix read, but will swap bytes on machines with
- * byte order opposite that of the VAX. This makes the font files portable.
- */
-
- sread(d, buf, nbytes)
- register char *buf;
- register int nbytes;
- {
- register char *test, l, r;
- short order = 1;
- int ret;
- test = (char*)(&order);
- ret = read(d, buf, nbytes);
- if (*test != '\001')
- {
- while( nbytes > 1) /* non-vax: do byte swap */
- {
- l = *buf++;
- r = *buf;
- *buf = l;
- *--buf = r;
- buf += 2;
- nbytes -= 2;
- }
- }
- return(ret);
- }
- SHAR_EOF
- chmod +x 'lemfont.c'
- if test -f 'lemgeo.c'
- then
- echo shar: over-writing existing file "'lemgeo.c'"
- fi
- cat << \SHAR_EOF > 'lemgeo.c'
- /*
- * lemgeo.c - low-level geometric routines
- *
- * copyright (c) by Alan W. Paeth, 1987. All rights reserved.
- */
-
- #include "lem.h"
-
- ptinrect(px, py, xl, yl, xh, yh, tol)
- {
- xl -= tol;
- yl -= tol;
- xh += tol;
- yh += tol;
- return((xl<=px) && (xh>=px) && (yl<=py) && (yh>=py));
- }
-
- hypot(x, y)
- {
- x = ABS(x);
- y = ABS(y);
- if (x>y) return(x+y/2);
- return(y+x/2);
- }
-
- dist(x0, y0, x1, y1)
- {
- return(hypot(x1-x0, y1-y0));
- }
-
- spacealign(x, y)
- int *x, *y;
- {
- int dx, dy;
- dx = ABS(*x-markx);
- dy = ABS(*y-marky);
- if (dx > FLATTOL * dy) *y = marky;
- if (dy > FLATTOL * dx) *x = markx;
- tickalign(x, y);
- }
- SHAR_EOF
- if test -f 'lemglobal.c'
- then
- echo shar: over-writing existing file "'lemglobal.c'"
- fi
- cat << \SHAR_EOF > 'lemglobal.c'
- /*
- * lemglobal.c -- global variables
- *
- * copyright (c) by Alan W. Paeth, 1987. All rights reserved.
- */
-
- #include "lem.h"
- #include "lemfont.h"
-
- /* global object array */
-
- pel objs[MAXOBJS];
- int lastobj;
-
- /* global font information */
-
- fontdir lemfont[RCLEN];
- BFont bfont[RCLEN];
-
- int rclen;
-
- /* command line globals */
-
- char *firstfile; /* name of first input dataset */
- int displayon; /* true if display is running */
-
- /* global cursor and screen info */
-
- int changes; /* objects added/deleted since last write */
- int tickflag, ticksize; /* true if ticks turned on, tick size [0..6] */
- int tx, ty; /* tick x,y spacing */
- int txoff, tyoff; /* tick x,y offset */
- int tickdot; /* hwidth of tick dot: 0/1 for DEC/SUN X-windows */
- int markx, marky; /* current mark */
- int markon; /* if any mark is present */
- int markobj; /* object number if mark is present and on an object */
- int anysel; /* if at least one selection */
-
- char gtype; /* default object creation */
- char galign; /* default alignment */
- char gemph; /* default emphasis */
- char gsize; /* default size */
-
- /* undo information */
-
- char undo; /* 'T' - transform 'M' - move 'U' - undelete */
- int unx,uny, unxe,unye; /* translation and affine transformation values */
- float un11, un12, un21, un22;
-
- int screenw, screenh; /* maximum screen size */
- int cred, cgreen, cwhite, cblack; /* system colors */
- char line[MAXCHAR]; /* input text line */
- char msgtext[MAXCHAR]; /* pending warning messages */
- char prompttext[MAXCHAR]; /* messages to the user */
- SHAR_EOF
- if test -f 'lemgroup.c'
- then
- echo shar: over-writing existing file "'lemgroup.c'"
- fi
- cat << \SHAR_EOF > 'lemgroup.c'
- /*
- * lemgroup.c - object group maintenance
- *
- * copyright (c) by Alan W. Paeth, 1987. All rights reserved.
- */
-
- #include "lem.h"
-
- addgroup()
- {
- int i, g;
- g = uniquegroup();
- forobjects
- {
- if (Osel) Ogroup = g;
- }
- }
-
- removegroup()
- {
- int i;
- forobjects
- {
- if (Ogroup) Ogroup = 0;
- }
- }
-
- uniquegroup()
- {
- int i, groups[256];
- for(i=0; i<256; i++) groups[i] = 0;
- for(i=1; i<lastobj; i++) groups[Ogroup]++;
- for(i=1; i<256; i++)
- {
- if (groups[i] == 0) break;
- }
- return(groups[i] == 0 ? i : 0);
- }
- SHAR_EOF
- if test -f 'lemhelp.c'
- then
- echo shar: over-writing existing file "'lemhelp.c'"
- fi
- cat << \SHAR_EOF > 'lemhelp.c'
- /*
- * lemhelp.c - give menu of key functions
- *
- * copyright (c) by Alan W. Paeth, 1987. All rights reserved.
- */
-
- #include "lem.h"
- #include "lemfont.h"
-
- #define HELPCHARS "[IHMABCDEFGLNOPRSTUVWX^?"
-
- help()
- {
- char c;
- msgpost("[help]: <space> - all; \"/\" - fonts; <key> - function: ");
- c = getstroke();
- if (c == ' ') helpall();
- else if (c == '/') helpfonts();
- else if (c != '\0') helpkey(c);
- }
-
- char *helpmsg(c)
- char c;
- {
- char *s;
- if (c < ' ') c += ' '; /* turn ^chars to upper case */
- switch(UC(c))
- {
- case '[': s = "ESC Delete Mark; Deselect all"; break;
- case 'A': s = "^A All select"; break;
- case 'B': s = "^B Box-ify selections"; break;
- case 'C': s = "^C Copy selections (in place)"; break;
- case 'D': s = "^D Delete selections"; break;
- case 'E': s = "^E Ellipse-ify selections"; break;
- case 'F': s = "^F Force<+key>: 0=reset/1-9=size/Bld/Nrm/Itl/Lft/Rht/Cen";break;
- case 'G': s = "^G Group selections"; break;
- case 'H': s = "BS Backspace input text"; break;
- case 'I': s = "TAB Select marked obj (cyclically)"; break;
- case 'L': s = "^L Refresh display"; break;
- case 'J':
- case 'M': s = "CR Add text (if present)"; break;
- case 'N': s = "^N No select (deselect all)"; break;
- case 'O': s = "^O Output PIC \"filename\""; break;
- case 'P': s = "^P Pop (ungroup -- instantiate) selected groups"; break;
- case 'Q': s = "^Q Quit"; break;
- case 'R': s = "^R Read \"filename\""; break;
- case 'S': s = "^Sc Special function escape"; break;
- case 'T': s = "^Td Tickmarks (on/off)"; break;
- case 'U': s = "^U Undo selections (undelete, untransform)"; break;
- case 'V': s = "^V Vector-ify selections"; break;
- case 'W': s = "^W Write \"filename\""; break;
- case 'X': s = "^X Cut lines (selections scissor normal lines)"; break;
- case '^': s = "^^ Help"; break;
- case '?': s = "^^? Help all"; break;
- default: s = " (undefined)"; break;
- }
- return(s);
- }
-
- helpkey(c)
- char c;
- {
- msgpost(helpmsg(c));
- }
-
- helpall()
- {
- int i, x, y;
- char c;
- erase();
- x = 10;
- y = screenh-fontleading(SYSFONT);
- for (i=0; i<strlen(HELPCHARS); i++)
- {
- int baseline;
- c = HELPCHARS[i];
- fontwrite(SYSFONT, x, y, helpmsg(c), EMPHNONE, HELPCOL);
- baseline = fontleading(SYSFONT);
- y -= baseline;
- if (y < baseline) break;
- }
- }
-
- helpfonts()
- {
- int i, x, y;
- char fontmsg[50];
- erase();
- x = 10;
- y = screenh-fontleading(SYSFONT);
- fontwrite(SYSFONT, x, y, "Current Fonts", EMPHNONE, HELPCOL);
- y -= 2 * fontleading(SYSFONT);
- for (i=1; i<rclen; i++)
- {
- int baseline;
- sprintf(fontmsg, "%d %s%d", i, lemfont[i].dsp, lemfont[i].psize);
- fontwrite(SYSFONT, x, y, fontmsg, EMPHNONE, HELPCOL);
- fontwrite(i, x+180, y, "regular", EMPHNONE, HELPCOL);
- fontwrite(i, x+280, y, "bold", EMPHBOLD, HELPCOL);
- fontwrite(i, x+380, y, "italic", EMPHITAL, HELPCOL);
- if (gsize == i)
- {
- char *S;
- S = (galign==ALIGNLEFT)?"[L]" : ((gemph==ALIGNRGHT)?"[R]":"[C]");
- if (gemph == EMPHNONE) fontwrite(i, x+160, y, S,EMPHNONE,HELPCOL);
- if (gemph == EMPHBOLD) fontwrite(i, x+260, y, S,EMPHBOLD,HELPCOL);
- if (gemph == EMPHITAL) fontwrite(i, x+360, y, S,EMPHITAL,HELPCOL);
- }
- baseline = fontleading(SYSFONT);
- y -= 2 * baseline;
- if (y < baseline) break;
- }
- }
- SHAR_EOF
- if test -f 'lemik.c'
- then
- echo shar: over-writing existing file "'lemik.c'"
- fi
- cat << \SHAR_EOF > 'lemik.c'
- /*
- * lemik.c - ikonas driver for lemming software
- *
- * copyright (c) by Alan W. Paeth, 1987. All rights reserved.
- */
-
- #include "lem.h"
-
- #include <graphics/ik_const.h>
- #include <local/Locator.h>
- #include <errno.h>
- #include <sys/time.h>
- #include <sgtty.h>
- #include <signal.h>
-
- #define MASKREG 0
- #define STDIN 0
- #define OBITS 0xffffff
- #define RED 0x0000ff
- #define GREEN 0x00ff00
- #define BLACK 0x000000
- #define WHITE 0xffffff
-
- struct In_config *Id, *Iopen();
- struct In_state st;
- char *inDevice, *getenv(), readchar();
-
- /* cursor stuff */
-
- #define CURLEN 32
- #define CUROFFX 16
- #define CUROFFY 16
- #define LCLK 49
- #define LWYOFF 33
-
- #define SETCUR(x, y) cur[(y)] |= 1<<((x));
- #define HL(a,b) (((a)<<16)+((b)&0xffff))
-
- static int cur[CURLEN];
-
- /*
- * external routines
- */
-
- setpixelrunh(x, y, wid, val)
- {
- int i;
- for (i=0; i<wid; i++)
- Ik_diowr(IK_XY_ADDR, x+i, 511-y, val);
- }
-
- setpixelrunv(x, y, wid, val)
- {
- int i;
- for (i=0; i<wid; i++)
- Ik_diowr(IK_XY_ADDR, x, 511-y+i, val);
- }
-
- start()
- {
- /*
- * system defaults
- */
- screenw = 512;
- screenh = 512;
- cred = RED;
- cgreen = GREEN;
- cblack = BLACK;
- cwhite = WHITE;
- tickdot = 1;
- /*
- * initialization
- */
- startcbreak();
- Ik_open();
- Ik_init();
- /* Ik_zoom_pan(0, 0, 508, 480, 0, 0, 1, 1, 0, 1); */ /* last for 1:1,not 4:3 */
- Ik_mask_set(MASKREG, OBITS);
- cursorenable();
-
- if( (inDevice = getenv("INPUT") ) == NULL )
- inDevice = "ikonas";
- if ( (Id = Iopen(inDevice, I_DEFAULT)) == NULL) err("can't open tablet");
- Iwindow( Id, 0, 511, 0, 511, 0, 32 );
- Ictl(Id, I_ENABLE, 0); /* make the tablet free-running *sigh* */
- }
-
- stop()
- {
- cursordisable();
- Iclose(Id);
- Ik_close();
- stopcbreak();
- }
-
- getevent(xdown, ydown, xup, yup, ch)
- char *ch;
- int *xdown, *ydown, *xup, *yup;
- {
- int lastx, lasty, mousedesc, dev;
- mousedesc = fileno(Id->In_ifp);
- dev = checkevent(mousedesc, STDIN, 1); /* blocking (hah!) */
- if (dev == STDIN)
- {
- *ch = readchar();
- return(((*ch < ' ') || (*ch == '\177')) ? CNTRL : ALPHA);
- }
- if (dev == mousedesc)
- {
- Iread(Id, &st, COORDINATES);
- cursorplace(st.x, st.y);
- lastx = st.x;
- lasty = st.y;
- if (st.button == 0) return(NOEVT);
- else
- {
- *xdown = st.x;
- *ydown = st.y;
- do {
- Iread(Id, &st, COORDINATES);
- *yup = st.y;
- *xup = st.x;
- if ((lastx != st.x) || (lasty != st.y)) cursorplace(st.x, st.y);
- lastx = st.x;
- lasty = st.y;
- } while (st.button != 0);
- }
- return(MOUSE);
- }
- return(NOEVT);
- }
-
- charshow(str)
- char *str;
- {
- fprintf(stdout, "%s", str);
- fflush(stdout);
- }
-
- charunshow(n)
- {
- int i;
- for (i=0; i<n; i++) fprintf(stdout, "%c %c", '\b', '\b');
- fflush(stdout);
- }
-
- drawvec(x0, y0, x1, y1, col, wid, emph)
- {
- drawline(x0, y0, x1, y1, wid, col, emph);
- }
-
- erase()
- {
- Ik_clear();
- }
-
- /*
- * internal routines
- */
-
- cursorenable()
- {
- long i;
- int ncolor[IK_MAP_SIZE];
- Ik_set_mode( SET_DURING_RETRACE );
- Ik_mask_set(0, 0xffffff);
- Ik_dmard(IK_WD_ADDR, IK_COLOUR_MAPS, IK_MAP_SIZE*0, ncolor, IK_MAP_SIZE);
- for (i=0; i<IK_MAP_SIZE; i++) ncolor[i] = (-1) ^ ncolor[i];
- Ik_dmawr(IK_WD_ADDR, IK_COLOUR_MAPS, IK_MAP_SIZE*1, ncolor, IK_MAP_SIZE);
- Ik_dmawr(IK_WD_ADDR, IK_COLOUR_MAPS, IK_MAP_SIZE*3, ncolor, IK_MAP_SIZE);
- Ik_diowr( IK_WD_ADDR, IK_XBAR_SWITCH, 32, 32); /* guarantee incursor bit */
- for (i=0; i<CURLEN; i++) cur[i] = 0; /* clear cursor */
- for (i=0; i<CURLEN/4; i++) /* draw open + sign */
- {
- SETCUR(i+CURLEN/8, CURLEN/2);
- SETCUR(7*CURLEN/8-i, CURLEN/2);
- SETCUR(CURLEN/2, i+CURLEN/8);
- SETCUR(CURLEN/2, 7*CURLEN/8-i);
- }
- Ik_curs_map(cur, CURLEN/2, CURLEN/2);
- cursorplace(0, 0);
- }
-
- cursordisable()
- {
- int i;
- for (i=0; i<CURLEN; i++) cur[i] = 0;
- Ik_curs_map(cur, 0, 0);
- Ik_diowr( IK_WD_ADDR, IK_FBC_REGS, FBC_MODE, HL(LCLK, 0x40));
- }
-
- cursorplace(x, y)
- {
- Ik_diowr(IK_WD_ADDR, IK_FBC_REGS, FBC_CURSOR,
- HL((511-y)+LWYOFF-CUROFFY-5, x-CUROFFX));
- Ik_diowr( IK_WD_ADDR, IK_FBC_REGS, FBC_MODE, HL(LCLK, 0x44));
- }
-
- /*
- * UNIX code to test for pending STDIN characters (in CBREAK mode)
- * and capture ^Z interruptions for the sake of CBREAK problems.
- */
-
- int stopcatch();
-
- stopcbreak()
- {
- struct sgttyb tty;
- ioctl(STDIN, TIOCGETP, &tty);
- tty.sg_flags &= ~CBREAK;
- tty.sg_flags |= ECHO;
- ioctl(STDIN, TIOCSETP, &tty);
- signal(SIGTSTP, SIG_DFL);
- }
-
- startcbreak()
- {
- struct sgttyb tty;
- ioctl(STDIN, TIOCGETP, &tty);
- tty.sg_flags |= CBREAK;
- tty.sg_flags &= ~ECHO;
- ioctl(STDIN, TIOCSETP, &tty);
- signal(SIGTSTP, stopcatch);
- }
-
- stopcatch()
- {
- /* ^Z just typed. */
- stopcbreak();
- sigsetmask (sigblock(0) & ~(1<<(SIGTSTP-1))); /* turn SIGTSTP on */
- kill(0, SIGTSTP); /* STOP THYSELF! */
- /* you just returned */
- startcbreak(); /* restore action for next time */
- }
-
- checkevent(l, r, blockflag)
- {
- extern int errno;
- int rdesc, retcode, bits;
- struct timeval tv;
- do {
- rdesc = (1<<l) | (1<<r);
- bits = (l > r) ? l+1 : r+1;
- bzero(&tv, sizeof tv); /* zero timer -> poll, no waiting */
- retcode = select(bits, &rdesc, 0, 0, blockflag ? 0 : &tv);
- } while ((retcode < 0) && (errno == EINTR));
- if (retcode <= 0) return(-1);
- return((rdesc == (1<<l)) ? l : r);
- }
-
- char readchar()
- {
- char ch;
- read(STDIN, &ch, 1);
- return(ch);
- }
-
- writescan(x, y, pixels, outaddr, color)
- int x, y, pixels, *outaddr, color;
- {
- static int IKbuf[512];
- int words, *bufbase;
-
- /* register */
- register int next, *wordbase, regfontcolor;
-
- if (pixels <= 0) return; /* PARANOIA: should not ever happen */
-
- regfontcolor = color; /* for a little speed */
- words = (pixels - 1) / 32 + 1;
- bufbase = IKbuf;
- Ik_dmard(IK_XY_ADDR, x, y, IKbuf, pixels);
-
- ++words;
- while (--words)
- {
- next = *outaddr;
- ++outaddr;
- wordbase = bufbase;
- while (next)
- {
- if (next < 0) *wordbase = regfontcolor;
- ++wordbase;
- next<<=1;
- }
- bufbase += 32;
- }
- Ik_dmawr(IK_XY_ADDR, x, y, IKbuf, pixels);
- }
- SHAR_EOF
- if test -f 'lemio.c'
- then
- echo shar: over-writing existing file "'lemio.c'"
- fi
- cat << \SHAR_EOF > 'lemio.c'
- /*
- * lemio.c - I/O routines
- *
- * copyright (c) by Alan W. Paeth, 1987. All rights reserved.
- */
-
- #include "lem.h"
-
- writefile()
- {
- int i;
- char *fname;
- FILE *f;
- if (lastobj == 1) return; /* nothing on display -- fast return */
- fname = prompt("output file: ");
- f = (fname && (strlen(fname) > 1)) ? fopen(fname, "w") : 0;
- if (f)
- {
- fprintf(f, "LEMMING %d\n", VERNO);
- forobjects
- {
- if (Onotdel)
- {
- fprintf(f, "%c %d %d %d %d %d %c %c",
- Otype, Oxs, Oys, Oxe, Oye, Osize, Oalign, Oemph);
- if (Otext && strlen(Otext)) fprintf(f, " \\%s", Otext);
- fprintf(f, "\n");
- }
- }
- fclose(f);
- changes = 0;
- msgpost("output done");
- }
- else msgpost("output failed");
- free(fname);
- }
-
- readfileint(fname)
- char *fname;
- {
- int i, g, ver;
- char *s, fline[MAXCHAR+50];
- FILE *f;
- f = 0;
- if (fname && (strlen(fname) > 0))
- {
- f = fopen(fname, "r");
- if (!f)
- {
- char filename[100];
- sprintf(filename, "%s.%s", fname, LEMEXTN);
- f = fopen(filename, "r");
- }
- }
- if (f)
- {
- fgets(fline, sizeof(fline), f);
- if ((sscanf(fline, "LEMMING %d", &ver) == 1) && (ver == VERNO))
- {
- g = uniquegroup();
- while (1)
- {
- int x0, y0, x1, y1, size;
- fgets(fline, sizeof(fline), f);
- if (feof(f)) break;
- i = objalloc(0);
- sscanf(fline, "%c %d %d %d %d %d %c %c", &Otype, &x0, &y0,
- &x1, &y1, &size, &Oalign, &Oemph);
- Oxs = x0;
- Oys = y0;
- Oxe = x1;
- Oye = y1;
- Osize = size;
- /*
- * possible input text
- */
- s = fline;
- while ((*s) && (*s != '\\')) s++;
- if (*s == '\\') s++;
- if (*s) s[strlen(s)-1] = '\0'; /* snuff trailing CR */
- Otext = (s && strlen(s)) ? salloc(s) : 0;
- /*
- * now assign attributes
- */
- Ogroup = g;
- Ostat = DEL;
- objresize(i);
- objectop(i, DEL, SEL);
- }
- fclose(f);
- msgpost("input done");
- }
- else msgpost("bogus input file");
- }
- else msgpost("input not found");
- }
-
- readfile()
- {
- char *fname;
- fname = prompt("input file: ");
- readfileint(fname);
- free(fname);
- }
- SHAR_EOF
- if test -f 'lemline.c'
- then
- echo shar: over-writing existing file "'lemline.c'"
- fi
- cat << \SHAR_EOF > 'lemline.c'
- /*
- * lemline.c - line primities
- *
- * copyright (c) by Alan W. Paeth, 1987. All rights reserved.
- */
-
- #include "lem.h"
-
- lineadd(x0, y0, x1, y1)
- {
- int i;
- if ((x0 == x1) && (y0 == y1)) return;
- i = objalloc(LINE);
- lineupdate(i, x0, y0, x1, y1);
- objnew(i);
- }
-
- lineresize(i)
- {
- }
-
- lineupdate(i, x0, y0, x1, y1)
- {
- Oxs = x0;
- Oys = y0;
- Oxe = x1;
- Oye = y1;
- }
-
- linenearpt(i, x, y)
- {
- int tol, hy;
- if (ptinrect(x, y, Oxl, Oyl, Oxh, Oyh, LINETOL) == 0) return(0);
- hy = hypot(Ow, Oh);
- if (hy < SHRTTOL) return(1);
- tol = ABS(((x-Ox)*Oh - (y-Oy)*Ow)) / hy;
- return(LINETOL > tol);
- }
-
- lineinrect(i, xl, yl, xh, yh)
- {
- return(ptinrect(Oxl, Oyl, xl, yl, xh, yh, LINETOL) &&
- ptinrect(Oxh, Oyh, xl, yl, xh, yh, LINETOL));
- }
-
- linecantug(i, x, y)
- {
- return(linenearpt(i, x, y));
- }
-
- linetug(i, xs, ys, xe, ye)
- {
- if (dist(Oxs, Oys, xs, ys) < TUGPROX) lineupdate(i, xe, ye, Oxe, Oye);
- else if (dist(Oxe, Oye, xs, ys) < TUGPROX) lineupdate(i, Oxs, Oys, xe, ye);
- else linemove(i, xe-xs, ye-ys);
- }
-
- linealign(i, x, y)
- int *x, *y;
- {
- if (dist(Oxs, Oys, *x, *y) < ENDTOL)
- {
- *x = Oxs;
- *y = Oys;
- }
- else if (dist(Oxe, Oye, *x, *y) < ENDTOL)
- {
- *x = Oxe;
- *y = Oye;
- }
- else
- {
- int frac;
- frac = (ABS(Ow) > ABS(Oh)) ? (12*(*x-Oxs)+6)/Ow : (12*(*y-Oys)+6)/Oh;
- *x = ((12-frac)*Oxs + frac*Oxe)/12;
- *y = ((12-frac)*Oys + frac*Oye)/12;
- }
- }
-
- linemove(i, x, y)
- {
- objsupmove(i, x, y);
- }
-
- lineaffine(i, m11, m12, m21, m22)
- float m11, m12, m21, m22;
- {
- objsupaffine(i, m11, m12, m21, m22, 1);
- }
-
- linedraw(i, col)
- {
- int wid;
- wid = lemfont[Osizer].thick;
- drawvec(Oxs, Oys, Oxe, Oye, col, wid, Oemph);
- if (Oalign == ALIGNLEFT)
- {
- int h, x, y, x1, y1;
- h = hypot(Ow, Oh)*13;
- x = Ow*ARROWLEN;
- y = Oh*ARROWLEN;
- x1 = ( x*12-y*5)/h;
- y1 = ( x*5+y*12)/h;
- drawvec(Oxs, Oys, Oxs+x1, Oys+y1, col, wid, EMPHNONE);
- x1 = ( x*12+y*5)/h;
- y1 = (-x*5+y*12)/h;
- drawvec(Oxs, Oys, Oxs+x1, Oys+y1, col, wid, EMPHNONE);
- }
- if (Oalign == ALIGNRGHT)
- {
- int h, x, y, x1, y1;
- h = hypot(Ow, Oh)*13;
- x = Ow*ARROWLEN;
- y = Oh*ARROWLEN;
- x1 = ( x*12-y*5)/h;
- y1 = ( x*5+y*12)/h;
- drawvec(Oxe, Oye, Oxe-x1, Oye-y1, col, wid, EMPHNONE);
- x1 = ( x*12+y*5)/h;
- y1 = (-x*5+y*12)/h;
- drawvec(Oxe, Oye, Oxe-x1, Oye-y1, col, wid, EMPHNONE);
- }
- }
- SHAR_EOF
- # End of shell archive
- exit 0
-
-
- --
-
- Rich $alz "Anger is an energy"
- Cronus Project, BBN Labs rsalz@bbn.com
- Moderator, comp.sources.unix sources@uunet.uu.net
-